<script>
import Engine from "../core/utils/engine";
import FullScreenInBackground from "../core/decorators/FullScreenInBackground";
import AnimatedText3D from "../core/objects/AnimatedText3D";
import { computed } from "@vue/reactivity";
import { Color, Group, Raycaster, Scene, Vector2, Vector3 } from "three";
import LineGenerator from "../core/objects/LineGenerator";
import getRandomFloat from "../core/utils/getRandomFloat";
import getRandomItem from "../core/utils/getRandomItem";
import { TimelineLite, Power3 } from "gsap";
import hasTouch from "../core/utils/hasTouch";
import HandleCameraOrbit from "../core/decorators/HandleCameraOrbit.js";
import PostProcessing from "../core/decorators/PostProcessing";
import AnimatedPlane from "../core/objects/AnimatedPlane";
import AnimatedButton from "../core/objects/AnimatedButton";
import { CSS3DRenderer } from "three-css3drenderer";
import {
  BlendFunction,
  EffectPass,
  OutlineEffect,
  SMAAEffect,
} from "postprocessing";
import { onMounted } from "@vue/runtime-core";

const selectionObject = [];

export default {
  setup() {
    const isMobile = computed(() => {
      return hasTouch();
    });

    @FullScreenInBackground
    @HandleCameraOrbit({ x: 4, y: 4 })
    @PostProcessing
    class CustomEngine extends Engine {}

    const engine = new CustomEngine();

    const group = new Group();

    /**
     * create Title
     */
    const text = new AnimatedText3D("WebPublish", {
      color: "#0f070a",
      size: 0.8,
    });
    // text.position.x -= 7;
    // text.rotation.set(0, 0.2, 0);
    group.add(text);

    /**
     * GetInfo
     */
    const promise = new Promise(async (resolve, reject) => {
      var versionText, downloadButton, downloadURL, releaseTime;
      const res = await fetch(
        "http://oss.tangweitian.cn/update/webpublish/latest.yml"
      );
      var data = await res.text();
      console.log(data);

      data = data.replace(/<\/?.+?>/g, ",");
      data = data.replace(/[\r\n]/g, ",");

      const dataList = data.split(",");
      dataList.forEach((d) => {
        if (versionText && downloadURL && releaseTime) {
          return;
        }
        if (!versionText && d.indexOf("version") !== -1) {
          versionText = new AnimatedText3D(d.replace("version: ", ""), {
            color: "#0f070a",
            size: 0.5,
          });

          versionText.position.x = 4.5;
          versionText.position.y -= 1;
          // versionText.rotation.set(0, 0.2, 0);
          group.add(versionText);
        } else if (!downloadURL && d.indexOf("path: ") !== -1) {
          downloadURL =
            "http://oss.tangweitian.cn/update/webpublish/" +
            d.replace("path: ", "");
          downloadButton = new AnimatedPlane("images/download.png", {
            size: 0.6,
            width: 3,
            height: 1,
          });
          downloadButton.position.x = 4.5;
          downloadButton.position.y -= 2;
          downloadButton.addEventListener("click", () => {
            window.open(downloadURL);
          });
          selectionObject.push(downloadButton.children[0]);
          // downloadButton.rotation.set(0, 0.2, 0);
          group.add(downloadButton);
        } else if (!releaseTime && d.indexOf("releaseDate: ") !== -1) {
          releaseTime = d.replace("releaseDate: ", "");
          releaseTime = releaseTime.replace("'", "");
        }
      });
      resolve([versionText, downloadButton]);
    });

    /**
     * gitee,github
     */
    const github = new AnimatedPlane("images/github.png", {
      // size: isMobile.value ? 0.4 : 0.6,
      width: 0.5,
      height: 0.5,
    });
    github.position.x = 4.5;
    github.position.y -= 3;
    // github.rotation.set(0, 0.2, 0);
    github.addEventListener("click", () => {
      window.location.href = "https://github.com/CandyACE/webpublish";
    });
    group.add(github);
    selectionObject.push(github.children[0]);

    const gitee = new AnimatedPlane("images/gitee.png", {
      // size: isMobile.value ? 0.4 : 0.6,
      width: 0.5,
      height: 0.5,
    });
    gitee.position.x = 5.5;
    gitee.position.y -= 3;
    gitee.addEventListener("click", () => {
      window.location.href = "https://gitee.com/tstwt/webpublish";
    });
    // gitee.rotation.set(0, 0.2, 0);
    group.add(gitee);
    selectionObject.push(gitee.children[0]);

    /**
     * Software
     */
    const plane = new AnimatedPlane("images/img.png", {
      size: 0.6,
    });
    if (isMobile.value) {
      plane.scale.set(0.4, 0.4, 0.4);
      plane.position.y -= .5;
      plane.position.x -= .45;
    } else {
      plane.rotation.set(0, -0.2, 0);
      plane.position.x += 4;
    }
    engine.add(plane);

    /**
     * addOutlinePass
     */
    const outlineEffect = new OutlineEffect(engine.scene, engine.camera, {
      blendFunction: BlendFunction.SCREEN,
      edgeStrength: 4,
      pulseSpeed: 0.0,
      visibleEdgeColor: 0xe8a852,
      hiddenEdgeColor: 0x22090a,
      height: 720,
      blur: true,
      xRay: true,
    });

    outlineEffect.setSelection([plane.children[0]]);
    outlineEffect.blurPass.kernelSize = 4;
    const outlinePass = new EffectPass(engine.camera, outlineEffect);
    outlinePass.enabled = false;

    engine.addPass(outlinePass, true);

    /**
     * Lignes
     */
    const COLORS = ["#4062BB", "#52489C", "#59C3C3", "#F45B69", "#F45B69"].map(
      (col) => new Color(col)
    );
    const STATIC_PROPS = {
      width: 0.1,
      nbrOfPoints: 5,
    };

    class CustomLineGenerator extends LineGenerator {
      addLine() {
        super.addLine({
          length: getRandomFloat(8, 15),
          visibleLength: getRandomFloat(0.05, 0.2),
          position: new Vector3(
            (Math.random() - 0.5) * 1.5,
            Math.random() - 1,
            (Math.random() - 0.5) * 2
          ).multiplyScalar(getRandomFloat(5, 20)),
          turbulence: new Vector3(
            getRandomFloat(-2, 2),
            getRandomFloat(0, 2),
            getRandomFloat(-2, 2)
          ),
          orientation: new Vector3(getRandomFloat(-0.8, 0.8), 1, 1),
          speed: getRandomFloat(0.004, 0.008),
          color: getRandomItem(COLORS),
        });
      }
    }

    const lineGenerator = new CustomLineGenerator(
      {
        frequency: 0.5,
      },
      STATIC_PROPS
    );
    engine.add(lineGenerator);

    window.engine = engine;
    window.group = group;

    if (isMobile.value) {
      group.position.x -= 2;
      group.position.y = 3;
      group.scale.set(0.5, 0.5, 0.5);
    } else {
      group.position.x -= 7;
      group.rotation.set(0, 0.2, 0);
    }
    engine.add(group);

    /**
     * MouseManager
     */
    const mouse = new Vector2();
    const raycaster = new Raycaster();
    document.addEventListener(
      "mousemove",
      (event) => {
        mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
        mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
        var res = renderRaycasterObj(mouse);
        document.body.style.cursor = res ? "pointer" : "default";
      },
      false
    );

    document.addEventListener("click", (event) => {
      mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
      mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
      var res = renderRaycasterObj(mouse);
      res &&
        res.object.parent.dispatchEvent({
          type: "click",
        });
    });

    function renderRaycasterObj(mouse) {
      raycaster.setFromCamera(mouse, engine.camera);
      var intersects = raycaster.intersectObjects(selectionObject);
      if (intersects.length > 0) {
        return intersects[0];
      }
      return null;
    }

    /**
     * Start
     */
    engine.start();
    const tlShow = new TimelineLite({
      delay: 0.2,
      onStart: () => {
        lineGenerator.start();
      },
    });
    tlShow.to(".overlay", 0.6, { autoAlpha: 0 });
    tlShow.fromTo(
      engine.lookAt,
      3,
      { y: -4 },
      { y: 0, ease: Power3.easeOut },
      "-=0.4"
    );
    tlShow.add(text.show, "-=2");
    tlShow.add(plane.show, "-=2");
    tlShow.add(() => {
      setTimeout(() => {
        outlinePass.enabled = true;
      }, 100);
    }, "-=2");
    tlShow.add(github.show, "-=2");
    tlShow.add(gitee.show, "-=2");
    promise.then((data) => {
      data.forEach((d) => {
        tlShow.add(d.show, "-=2");
      });
    });
  },
};
</script>


<template>
  <div class="engine"></div>
</template>

<style scoped>
.engine {
  /* // position: absolute;
  // margin: 0;
  // padding: 0;
  // width: 100%;
  // height: 100%;
  // top: 0;
  // left: 0; */
}
</style>